import logging
from logging.handlers import RotatingFileHandler
from abc import ABCMeta
from util.timeUtil import *
from pynput import keyboard
from pynput.mouse import Button
from wowThread.threadJob import *
import random
import gc
from util.configUtil import *
from util.ocrBloodPercentage import *
from util.healerCheckOtherBloodBarUtil import *
from util.mainUtil import *
from util.clientUtil import *

import numpy as np
from PIL import ImageGrab, Image
import datetime
from apscheduler.schedulers.background import BackgroundScheduler
import win32gui, win32api, win32con, win32ui

logging.config.fileConfig("./util/logging.conf")
logging.basicConfig(filename='yhbtestingameing.log', level=logging.DEBUG, force=True)
log = logging.getLogger("example")

"""
    父类描述：
        1、尽量各个职业都写到父类的共有层里面，实在有自己特殊在再写到自己的类里面
        2、如果子类有特定的定制，那么就在子类中对不同的部分进行定制，绝大部分还是用的父类中的代码
"""


class Player(metaclass=ABCMeta):
    # 通过构造函数传递过来大量的参数，通过key value值的方式来获取这些参数
    """
        构造函数：
            1、通过构造函数传递过来大量的参数，通过key value值的方式来获取这些参数
    """
    # 魔兽世界的NugComboBar，对应的捕捉高度和宽度
    NugComboBarDeltaX = 11
    NugComboBarDeltaY = 10

    # 魔兽世界底部按钮第一个激活与否，激活了会高亮
    Button1DeltaX = 18
    Button1DeltaY = 1
    ButtonWidth = 43

    # 龙希尔蓄力条
    WACastBarY = getIniInt("./util", "xyCastBar", "y1")
    WACastBarWidth = getIniInt("./util", "xyCastBar", "width")
    WACastBarX = getIniInt("./util", "xyCastBar", "x1")

    # 血条
    WABloodBarY = getIniInt("./util", "xyBloodBar", "y1")
    WABloodBarWidth = getIniInt("./util", "xyBloodBar", "width")
    WABloodBarX = getIniInt("./util", "xyBloodBar", "x1")
    WABloodBarGap1InY = getIniInt("./util", "xyBloodBar", "gap1InY")
    # 魔法MP条
    WAMagicBarY = getIniInt("./util", "xyMagicBar", "y1")
    WAMagicBarWidth = getIniInt("./util", "xyMagicBar", "width")
    WAMagicBarX = getIniInt("./util", "xyMagicBar", "x1")

    # 能量条
    WAEnergyBarY = getIniInt("./util", "xyEnergyBar", "y1")
    WAEnergyBarWidth = getIniInt("./util", "xyEnergyBar", "width")
    WAEnergyBarX = getIniInt("./util", "xyEnergyBar", "x1")

    # 底部坦克的血条和自己血条之间y方向的位置差异
    WABlood1_Blood2_DeltaY = 26
    WABloodBarDeltaX = 3
    WABloodBarDeltaY = 3
    WAMagicBarDeltaX = 3
    WAMagicBarDeltaY = 3
    # 原来红色平均值是186，后面不用wa，用暴雪绿色的血条，green，也用了185的颜色均值
    WABloodBarAvgColor = 185

    # 武僧T神级插件，右边的小方块，到粉色，还没到红色
    WA_WST_GODPLUG_PINK_NOT_RED = 210
    # 武僧T神级插件，右边的小方块，到血红色
    WA_WST_GODPLUG_RED = 253
    # 武僧T神级插件，酒池百分比,大数字(70%虹)   x:707  y:335  w:26  h:13
    WA_WST_GODPLUG_RED_WINE_NUMBER = 142
    WA_WST_GODPLUG_RED_WINE_NUMBER_W = 26
    WA_WST_GODPLUG_RED_WINE_NUMBER_H = 13
    # 230
    WA_SQUARE_ZFX_AvgColor = 230
    WA_SQUARE_ZFX = getIniInt("./util", "xyStatusSquare", "y1")
    WA_SQUARE_ZFX_X1 = getIniInt("./util", "xyStatusSquare", "x1")
    WA_SQUARE_ZFX_X2 = getIniInt("./util", "xyStatusSquare", "x1") + 1 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X3 = getIniInt("./util", "xyStatusSquare", "x1") + 2 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X4 = getIniInt("./util", "xyStatusSquare", "x1") + 3 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X5 = getIniInt("./util", "xyStatusSquare", "x1") + 4 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X6 = getIniInt("./util", "xyStatusSquare", "x1") + 5 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X7 = getIniInt("./util", "xyStatusSquare", "x1") + 6 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X8 = getIniInt("./util", "xyStatusSquare", "x1") + 7 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X9 = getIniInt("./util", "xyStatusSquare", "x1") + 8 * getIniInt("./util", "xyStatusSquare", "width")

    # 能量星星点数
    WA_STAR_Y = getIniInt("./util", "xyStar", "y1")
    WA_STAR_X1 = getIniInt("./util", "xyStar", "x1")
    WA_STAR_X2 = getIniInt("./util", "xyStar", "x1") + 1 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X3 = getIniInt("./util", "xyStar", "x1") + 2 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X4 = getIniInt("./util", "xyStar", "x1") + 3 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X5 = getIniInt("./util", "xyStar", "x1") + 4 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X6 = getIniInt("./util", "xyStar", "x1") + 5 * getIniInt("./util", "xyStar", "width")

    # za的武僧T的比较号的插件，判断酒池红了后需要吃就消醉拳，否则就危险的一个判断
    WA_WST_X = getIniInt("./util", "wst_za_red", "x")
    WA_WST_Y = getIniInt("./util", "wst_za_red", "y")
    WA_WST_W = getIniInt("./util", "wst_za_red", "w")
    WA_WST_H = getIniInt("./util", "wst_za_red", "h")
    WA_WST_AVG_COLOR = getIniInt("./util", "wst_za_red", "avgColor")

    # 蓝条
    RED = 'r'
    GREEN = 'g'
    BLUE = 'b'
    ELSEKEY_NONE = 'NONE'
    ELSEKEY_0 = '0'
    ELSEKEY_1 = '1'
    ELSEKEY_2 = '2'
    ELSEKEY_3 = '3'
    ELSEKEY_4 = '4'
    ELSEKEY_5 = '5'
    ELSEKEY_6 = '6'
    ELSEKEY_7 = '7'
    ELSEKEY_8 = '8'
    ELSEKEY_9 = '9'
    ELSEKEY_f9 = Key.f9
    ELSEKEY_NONE = 'NONE'

    DEBUG_OPEN = 'DEBUG'
    DEBUG_CLOSE = ''

    WAITINGSECOND = 0.06

    WAITINGSECOND01 = 0.1
    WAITINGSECOND02 = 0.2
    WAITINGSECOND03 = 0.3
    WAITINGSECOND04 = 0.4

    # stopLoop = False

    stopShareLoop = False

    AOE = False

    # if else中的eelse键按的逻辑，有种是不触发的逻辑
    ELSEKEY_EMPTY = ''

    # 全局计数器
    countPlusPlus = 0

    schedulerInGame1 = BackgroundScheduler()
    schedulerInGame2 = BackgroundScheduler()
    schedulerInGame3 = BackgroundScheduler()
    schedulerInGame4 = BackgroundScheduler()
    schedulerInGame5 = BackgroundScheduler()
    schedulerInGame6 = BackgroundScheduler()
    schedulerInGame7 = BackgroundScheduler()
    schedulerInGame8 = BackgroundScheduler()
    schedulerInGame9 = BackgroundScheduler()
    schedulerInGame10 = BackgroundScheduler()
    # 血条百分比
    tiggerHP100_90 = BackgroundScheduler()
    tiggerHP90_80 = BackgroundScheduler()
    tiggerHP80_70 = BackgroundScheduler()
    tiggerHP70_60 = BackgroundScheduler()
    tiggerHP60_50 = BackgroundScheduler()
    tiggerHP50_40 = BackgroundScheduler()
    tiggerHP40_30 = BackgroundScheduler()

    def __init__(self, *args, **kwargs):
        # 构造函数
        # print("init %s" % self.__class__)
        # print("in player:self.frozenKeyPress1:" + str(args[0]))
        self.stillCanCreateNewThread = kwargs['stillCanCreateNewThread']
        self.frozenKeyPress = kwargs['frozenKeyPress']
        self.threadPoolKeyboard = kwargs['threadPoolKeyboard']
        self.threadPoolMouse = kwargs['threadPoolMouse']
        # self.race = kwargs['race']
        self.kb = kwargs['kb']
        self.ms = kwargs['ms']
        self.sem = kwargs['sem']
        self.gcDuringMousemoveObj = kwargs['gcDuringMousemoveObj']
        self.ui = kwargs['ui']
        return

    def setMainWindow(self, obj):
        self.MainWindow = obj

    def startScheduler1(self):
        self.schedulerInGame1.remove_all_jobs()
        self.schedulerInGame1.add_job(func=self.CallBackScheduler1, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo1')
        if self.schedulerInGame1.running != True:
            self.schedulerInGame1.start()
        return

    def startScheduler2(self):
        self.schedulerInGame2.remove_all_jobs()
        self.schedulerInGame2.add_job(func=self.CallBackScheduler2, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo2')
        if self.schedulerInGame2.running != True:
            self.schedulerInGame2.start()
        return

    def startScheduler3(self):
        self.schedulerInGame3.remove_all_jobs()
        self.schedulerInGame3.add_job(func=self.CallBackScheduler3, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo3')
        if self.schedulerInGame3.running != True:
            self.schedulerInGame3.start()
        return

    def startScheduler4(self):
        self.schedulerInGame4.remove_all_jobs()
        self.schedulerInGame4.add_job(func=self.CallBackScheduler4, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo4')
        if self.schedulerInGame4.running != True:
            self.schedulerInGame4.start()
        return

    def startScheduler5(self):
        self.schedulerInGame5.remove_all_jobs()
        self.schedulerInGame5.add_job(func=self.CallBackScheduler5, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo5')
        if self.schedulerInGame5.running != True:
            self.schedulerInGame5.start()
        return

    def startScheduler6(self):
        self.schedulerInGame6.remove_all_jobs()
        self.schedulerInGame6.add_job(func=self.CallBackScheduler6, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo6')
        if self.schedulerInGame6.running != True:
            self.schedulerInGame6.start()
        return

    def startScheduler7(self):
        self.schedulerInGame7.remove_all_jobs()
        self.schedulerInGame7.add_job(func=self.CallBackScheduler7, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo7')
        if self.schedulerInGame7.running != True:
            self.schedulerInGame7.start()
        return

    def startScheduler8(self):
        self.schedulerInGame8.remove_all_jobs()
        self.schedulerInGame8.add_job(func=self.CallBackScheduler8, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo8')
        if self.schedulerInGame8.running != True:
            self.schedulerInGame8.start()
        return

    def startScheduler9(self):
        self.schedulerInGame9.remove_all_jobs()
        self.schedulerInGame9.add_job(func=self.CallBackScheduler9, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo9')
        if self.schedulerInGame9.running != True:
            self.schedulerInGame9.start()
        return

    def startScheduler10(self):
        self.schedulerInGame10.remove_all_jobs()
        self.schedulerInGame10.add_job(func=self.CallBackScheduler10, trigger='date',
                                       next_run_time=datetime.datetime.now(), id='yehaibo10')
        if self.schedulerInGame10.running != True:
            self.schedulerInGame10.start()
        return

    def startTiggerHP100_90(self):
        self.tiggerHP100_90.remove_all_jobs()
        self.tiggerHP100_90.add_job(func=self.CallBackHP100_90, trigger='date',
                                    next_run_time=datetime.datetime.now(), id='yehaibo_a')
        if self.tiggerHP100_90.running != True:
            self.tiggerHP100_90.start()
        return

    def startTiggerHP90_80(self):
        self.tiggerHP90_80.remove_all_jobs()
        self.tiggerHP90_80.add_job(func=self.CallBackHP90_80, trigger='date',
                                   next_run_time=datetime.datetime.now(), id='yehaibo_b')
        if self.tiggerHP90_80.running != True:
            self.tiggerHP90_80.start()
        return

    def startTiggerHP80_70(self):
        self.tiggerHP80_70.remove_all_jobs()
        self.tiggerHP80_70.add_job(func=self.CallBackHP80_70, trigger='date',
                                   next_run_time=datetime.datetime.now(), id='yehaibo_c')
        if self.tiggerHP80_70.running != True:
            self.tiggerHP80_70.start()
        return

    def startTiggerHP70_60(self):
        self.tiggerHP70_60.remove_all_jobs()
        self.tiggerHP70_60.add_job(func=self.CallBackHP70_60, trigger='date',
                                   next_run_time=datetime.datetime.now(), id='yehaibo_d')
        if self.tiggerHP70_60.running != True:
            self.tiggerHP70_60.start()
        return

    def startTiggerHP60_50(self):
        self.tiggerHP60_50.remove_all_jobs()
        self.tiggerHP60_50.add_job(func=self.CallBackHP60_50, trigger='date',
                                   next_run_time=datetime.datetime.now(), id='yehaibo_e')
        if self.tiggerHP60_50.running != True:
            self.tiggerHP60_50.start()
        return

    def startTiggerHP50_40(self):
        self.tiggerHP50_40.remove_all_jobs()
        self.tiggerHP50_40.add_job(func=self.CallBackHP50_40, trigger='date',
                                   next_run_time=datetime.datetime.now(), id='yehaibo_f')
        if self.tiggerHP50_40.running != True:
            self.tiggerHP50_40.start()
        return

    def startTiggerHP40_30(self):
        self.tiggerHP40_30.remove_all_jobs()
        self.tiggerHP40_30.add_job(func=self.CallBackHP40_30, trigger='date',
                                   next_run_time=datetime.datetime.now(), id='yehaibo_g')
        if self.tiggerHP40_30.running != True:
            self.tiggerHP40_30.start()
        return

    def stopScheduler1(self):
        self.schedulerInGame1.pause_job(job_id='yehaibo1')
        # self.schedulerInGame1.remove_all_jobs()

    def stopScheduler3(self):
        self.schedulerInGame3.pause_job(job_id='yehaibo3')
        # self.schedulerInGame3.remove_all_jobs()

    # def stopScheduler1(self):
    #     self.schedulerInGame1.pause_job(job_id='yehaibo1')
    #     self.schedulerInGame2.pause_job(job_id='yehaibo2')
    #     self.schedulerInGame3.pause_job(job_id='yehaibo3')
    #     self.schedulerInGame4.pause_job(job_id='yehaibo4')
    #     self.schedulerInGame5.pause_job(job_id='yehaibo5')
    #     self.schedulerInGame6.pause_job(job_id='yehaibo6')
    #     self.schedulerInGame7.pause_job(job_id='yehaibo7')
    #     self.schedulerInGame8.pause_job(job_id='yehaibo8')
    #     self.schedulerInGame9.pause_job(job_id='yehaibo9')
    #     self.schedulerInGame10.pause_job(job_id='yehaibo10')

    def CallBackScheduler1(self):
        return

    def CallBackScheduler2(self):
        return

    def CallBackScheduler3(self):
        return

    def CallBackScheduler4(self):
        return

    def CallBackScheduler5(self):
        return

    def CallBackScheduler6(self):
        return

    def CallBackScheduler7(self):
        return

    def CallBackScheduler8(self):
        return

    def CallBackScheduler9(self):
        return

    def CallBackScheduler10(self):
        return

    def CallBackHP100_90(self):
        return

    def CallBackHP90_80(self):
        return

    def CallBackHP80_70(self):
        return

    def CallBackHP70_60(self):
        return

    def CallBackHP60_50(self):
        return

    def CallBackHP50_40(self):
        return

    def CallBackHP40_30(self):
        return

    '''
            魔兽世界中得桌面显示游戏界面，自己键盘数据都在界面中操作，通过下面得api，也可以将识别出来得框画到魔兽世界显示得界面上
            conda activate wow3.6
            pip install pywin32==300
    '''

    def drawRec(self, argw=0, argh=0, argtopleft=(0, 0), argColor=0):
        '''截图，输出Bitmapsbits的列表
        argw=0表示全宽，argh=0表示全高
        '''
        hwnd = 0  # 窗口的编号，0号表示当前活跃窗口
        hwndDC = win32gui.GetWindowDC(hwnd)  # 根据窗口句柄获取窗口的设备上下文DC（Divice Context）
        mfcDC = win32ui.CreateDCFromHandle(hwndDC)  # 根据窗口的DC获取mfcDC
        saveDC = mfcDC.CreateCompatibleDC()  # mfcDC创建可兼容的DC
        saveBitMap = win32ui.CreateBitmap()  # 创建bigmap准备保存图片
        MoniterDev = win32api.EnumDisplayMonitors(None, None)  # 获取监控器信息
        # 判断是否设置截图区域
        w = MoniterDev[0][2][2] if argw == 0 else argw
        h = MoniterDev[0][2][3] if argh == 0 else argh
        saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)  # 为bitmap开辟空间
        saveDC.SelectObject(saveBitMap)  # 高度saveDC，将截图保存到saveBitmap中
        # 截取从左上角（0，0）或者 tmptl 长宽为（w，h）的图片
        tx = 0 if argtopleft[0] <= 0 else argtopleft[0]
        ty = 0 if argtopleft[1] <= 0 else argtopleft[1]
        tmptl = (tx, ty)
        saveDC.BitBlt((0, 0), (w, h), mfcDC, tmptl, win32con.SRCCOPY)  # 目标矩形顶点(0,0)长宽(w,h),源设备mfcDC,源矩形顶点tmptl
        rtns = saveBitMap.GetBitmapBits()
        # # 绘制辅助框 暂时未解决透明问题
        hPen = win32gui.CreatePen(win32con.PS_SOLID, 1, argColor)  # 定义框颜色
        win32gui.SelectObject(hwndDC, hPen)
        hbrush = win32gui.GetStockObject(win32con.NULL_BRUSH)  # 定义透明画刷，这个很重要！！
        prebrush = win32gui.SelectObject(hwndDC, hbrush)
        win32gui.Rectangle(hwndDC, tx - 1, ty - 1, tx + w + 2, ty + h + 2)  # 左上到右下的坐标
        win32gui.SelectObject(hwndDC, prebrush)
        # # 回收资源
        mfcDC.DeleteDC()
        saveDC.DeleteDC()
        win32gui.DeleteObject(hPen)
        win32gui.DeleteObject(hbrush)
        win32gui.DeleteObject(prebrush)
        win32gui.ReleaseDC(hwnd, hwndDC)
        return rtns

    '''
        左下角的正方形是否显示出来红块了
    '''

    def isLeftBottonZFXShow(self, x, y, w, h, avgNumber):
        # 某个区域内出现了，加强buffer开始，就按按到buffer瞬间消失

        log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
        # sleep(sleepSecond)  # 避免CPU占用太高
        # 左下角，永远是用三通道中的红色
        RGBMode = 'r'
        ################################Button1##########################################
        imButton1 = ImageGrab.grab(
            bbox=(x - w / 2, y - h / 2, x + w / 2, y + h / 2))  # X1,Y1,X2,Y2
        imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
            (imButton1.size[1], imButton1.size[0], 3))
        imButton1_pil = Image.fromarray(imButton1_numpy)
        rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
        avgButton1_color = 0
        if RGBMode == 'r':
            rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = rButton1.getpixel((0, 0))
        elif RGBMode == 'g':
            gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = gButton1.getpixel((0, 0))
        elif RGBMode == 'b':
            bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = bButton1.getpixel((0, 0))
        ################################End##########################################
        if avgButton1_color > avgNumber:
            return True
        else:
            return False

    '''
        血条是否已经低于某个百分比
    '''

    def isBloodBarBelowPercentage(self, x, y, w, h, avgNumber):
        # 平均像素，触发是否按键
        if self.ui.stopLoop == False:
            log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
            # sleep(sleepSecond)  # 避免CPU占用太高
            # 血条永远是用的三通道中的r红色通道
            RGBMode = 'r'
            ################################Button1##########################################
            imButton1 = ImageGrab.grab(
                bbox=(x, y, x + w, y + h))  # X1,Y1,X2,Y2
            imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
                (imButton1.size[1], imButton1.size[0], 3))
            imButton1_pil = Image.fromarray(imButton1_numpy)
            rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
            avgButton1_color = 0
            if RGBMode == 'r':
                rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = rButton1.getpixel((0, 0))
            elif RGBMode == 'g':
                gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = gButton1.getpixel((0, 0))
            elif RGBMode == 'b':
                bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = bButton1.getpixel((0, 0))
            ################################End##########################################
            if avgButton1_color > avgNumber:
                return False
            else:
                return True
        else:
            return False

    '''
        祖先类中一个重要的对区域的平均像素的判断方法
        RGBMode:r;g;b;
        BigSmallmode:big,small   和区域缩成点后像素的平均值的比较
        triggerKey: 满足条件触发按的key
        loopNumber: 点击按键次数
        elseKey: 其他按键
        debugMode: 取了界面的绝对位置，怕不准，因此偶尔要打出来，看看位置是否准确了
    '''

    def pubAvgColorTiggerKeyBloodBarMode(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey, sleepSecond,
                                         loopNumber, elseKey, debugMode):

        if self.ui.stopLoop == False:
            # 平均像素，触发是否按键
            # 原来是红色血条，后面不是红色，掉血危险了，因此触发一些保命技能
            ####################################################检查取的位置是否正确
            if debugMode == 'DEBUG':
                drawRec(int(w), int(h), (int(x), int(y)), win32api.RGB(0, 255, 0), width=8)

            log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
            sleep(sleepSecond)  # 避免CPU占用太高
            ################################Button1##########################################
            imButton1 = ImageGrab.grab(
                bbox=(x, y, x + w, y + h))  # X1,Y1,X2,Y2
            imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
                (imButton1.size[1], imButton1.size[0], 3))
            imButton1_pil = Image.fromarray(imButton1_numpy)
            rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
            avgButton1_color = 0
            if RGBMode == 'r':
                rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = rButton1.getpixel((0, 0))
            elif RGBMode == 'g':
                gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = gButton1.getpixel((0, 0))
            elif RGBMode == 'b':
                bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = bButton1.getpixel((0, 0))
            ################################End##########################################

            if BigSmallmode == 'big':
                if avgButton1_color > avgNumber:
                    for i in range(1, loopNumber):
                        self.click(self.kb, triggerKey, 3)
                        sleep(0.2)
                else:
                    if elseKey != 'NONE':
                        for i in range(1, 2):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            elif BigSmallmode == 'small':
                if avgButton1_color < avgNumber:
                    for i in range(1, loopNumber):
                        self.click(self.kb, triggerKey, 3)
                        sleep(0.2)
                else:
                    if elseKey != 'NONE':
                        for i in range(1, 2):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            return avgButton1_color
        else:
            return 0

    def pubAvgColorTiggerKeyCDMode(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey, sleepSecond,
                                   loopNumber, elseKey, debugMode):
        # cd key,和buff mode不一样，cdkey是出现了，不要多按了，buffermodule，是出现了，要使劲按
        if self.ui.stopLoop == False:
            # 平时按键一直按，某个区域内出现了，就停止按了，避免按键CPU，以及避免浪费技能(暴雨图腾模式)
            # elseKey：没有匹配上的时候，补基础按键
            ####################################################检查取的位置是否正确
            if debugMode == 'DEBUG':
                drawRec(int(w), int(h), (int(x), int(y)), win32api.RGB(0, 255, 0), width=8)

            log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
            sleep(sleepSecond)  # 避免CPU占用太高
            ################################Button1##########################################
            imButton1 = ImageGrab.grab(
                bbox=(x - w / 2, y - h / 2, x + w / 2, y + h / 2))  # X1,Y1,X2,Y2
            imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
                (imButton1.size[1], imButton1.size[0], 3))
            imButton1_pil = Image.fromarray(imButton1_numpy)
            rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
            avgButton1_color = 0
            if RGBMode == 'r':
                rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = rButton1.getpixel((0, 0))
            elif RGBMode == 'g':
                gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = gButton1.getpixel((0, 0))
            elif RGBMode == 'b':
                bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = bButton1.getpixel((0, 0))
            ################################End##########################################

            if BigSmallmode == 'big':
                if avgButton1_color > avgNumber:
                    print('xxxxxx11111')
                    if elseKey != 'NONE':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
                else:
                    print('xxxxxx222222')
                    for i in range(0, loopNumber):
                        self.click(self.kb, triggerKey, 3)
                        sleep(0.2)
            elif BigSmallmode == 'small':
                if avgButton1_color < avgNumber:
                    print('xxxxxxaaaaa')
                    for i in range(0, loopNumber):
                        self.click(self.kb, triggerKey, 3)
                        sleep(0.2)
                else:
                    print('xxxxxxbbbbb')
                    if elseKey != 'NONE':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            return avgButton1_color
        else:
            return 0

    def pubAvgColorTiggerKeyBuffMode(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey, sleepSecond,
                                     loopNumber, elseKey, debugMode):
        # cd key,和buff mode不一样，cdkey是出现了，不要多按了，buffermodule，是出现了，要使劲按
        if self.ui.stopLoop == False:
            # 某个区域内出现了，加强buffer开始，就按按到buffer瞬间消失
            if debugMode == 'DEBUG':
                drawRec(int(w), int(h), (int(x), int(y)), win32api.RGB(0, 255, 0), width=8)

            log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
            sleep(sleepSecond)  # 避免CPU占用太高
            ################################Button1##########################################
            imButton1 = ImageGrab.grab(
                bbox=(x - w / 2, y - h / 2, x + w / 2, y + h / 2))  # X1,Y1,X2,Y2
            imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
                (imButton1.size[1], imButton1.size[0], 3))
            imButton1_pil = Image.fromarray(imButton1_numpy)
            rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
            avgButton1_color = 0
            if RGBMode == 'r':
                rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = rButton1.getpixel((0, 0))
            elif RGBMode == 'g':
                gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = gButton1.getpixel((0, 0))
            elif RGBMode == 'b':
                bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = bButton1.getpixel((0, 0))
            ################################End##########################################

            logging.debug("avgButton1_color:" + str(avgButton1_color))
            if BigSmallmode == 'big':
                if avgButton1_color > avgNumber:
                    for i in range(0, loopNumber):
                        self.click(self.kb, triggerKey, 3)
                        sleep(0.2)
                else:
                    if elseKey != 'NONE':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            elif BigSmallmode == 'small':
                if avgButton1_color < avgNumber:
                    print('xxxxxxaaaaa')
                    for i in range(0, loopNumber):
                        self.click(self.kb, triggerKey, 3)
                        sleep(0.2)
                else:
                    print('xxxxxxbbbbb')
                    if elseKey != 'NONE':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            return avgButton1_color
        else:
            return 0

    def pubAvgColorTiggerKeyAndStopClickTwice(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey,
                                              sleepSecond, loopNumber, stopx, stopy, stopwidth, stopheight, stopColor,
                                              stopSecond, stopModel, elseKey):
        if self.ui.stopLoop == False:
            # 第一轮坐标是血条，第二轮坐标是狂暴回血是否出来的坐标判断，防止多按一次，浪费技能(浪费了，后面就没技能了)
            # 血条在扣，扣到一定程度，就触发一定的保护技能

            log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))

            ################################Button1##########################################
            imButton1 = ImageGrab.grab(
                bbox=(x, y, x + w, y + h))  # X1,Y1,X2,Y2
            imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
                (imButton1.size[1], imButton1.size[0], 3))
            imButton1_pil = Image.fromarray(imButton1_numpy)
            rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
            avgButton1_color = 0
            if RGBMode == 'r':
                rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = rButton1.getpixel((0, 0))
            elif RGBMode == 'g':
                gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = gButton1.getpixel((0, 0))
            elif RGBMode == 'b':
                bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = bButton1.getpixel((0, 0))
            ################################End##########################################

            if BigSmallmode == 'big':
                if avgButton1_color > avgNumber:
                    # 点击前判断是否已经释放了狂暴回复，避免连续点第二次浪费(wa弄出来的一个正方形颜色块)
                    avgDruidBlood = self.pubAvgColorNoTrigger(stopx, stopy, stopwidth, stopheight, stopColor,
                                                              stopSecond)
                    if stopModel == 'small':
                        if avgDruidBlood < 230:
                            for i in range(1, loopNumber):
                                self.click(self.kb, triggerKey, 3)
                                sleep(0.2)
                        else:
                            if elseKey != 'NONE':
                                for i in range(0, 1):
                                    self.click(self.kb, elseKey, 2)
                                    sleep(0.1)
                    else:
                        if elseKey != 'NONE':
                            for i in range(0, 1):
                                self.click(self.kb, elseKey, 2)
                                sleep(0.1)
                else:
                    if elseKey != 'NONE':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            elif BigSmallmode == 'small':
                if avgButton1_color < avgNumber:
                    # 点击前判断是否已经释放了狂暴回复，避免连续点第二次浪费(wa弄出来的一个正方形颜色块)
                    print('wanyanwanyan')
                    avgDruidBlood = self.pubAvgColorNoTrigger(stopx, stopy, stopwidth, stopheight, stopColor,
                                                              stopSecond)
                    if stopModel == 'small':
                        if avgDruidBlood < 230:
                            print('kaikaikaikai')
                            for i in range(1, loopNumber):
                                self.click(self.kb, triggerKey, 3)
                                sleep(0.2)
                                print('yehaiboyehaibo')
                        else:
                            if elseKey != 'NONE':
                                for i in range(0, 1):
                                    self.click(self.kb, elseKey, 2)
                                    sleep(0.1)
                    else:
                        if elseKey != 'NONE':
                            for i in range(0, 1):
                                self.click(self.kb, elseKey, 2)
                                sleep(0.1)
                else:
                    print('zuozuozuo')
                    if elseKey != 'NONE':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            sleep(sleepSecond)  # 避免CPU占用太高
            return avgButton1_color
        else:
            return 0

    def pubAvgColorNoTrigger(self, x, y, w, h, RGBMode, sleepSecond):

        if self.ui.stopLoop == False:
            # 仅仅获取颜色，没有任何动作
            log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
            sleep(sleepSecond)  # 避免CPU占用太高
            ################################Button1##########################################
            imButton1 = ImageGrab.grab(
                bbox=(x, y, x + w, y + h))  # X1,Y1,X2,Y2
            imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
                (imButton1.size[1], imButton1.size[0], 3))
            imButton1_pil = Image.fromarray(imButton1_numpy)
            rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
            avgButton1_color = 0
            if RGBMode == 'r':
                rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = rButton1.getpixel((0, 0))
            elif RGBMode == 'g':
                gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = gButton1.getpixel((0, 0))
            elif RGBMode == 'b':
                bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = bButton1.getpixel((0, 0))
            return avgButton1_color
        else:
            return 0

    def pubAvgColorHPPercentageNoTrigger(self, iPercentage, RGBMode, sleepSecond,debugMode):
        # HP Bloodbar percentage
        if self.ui.stopLoop == False:

            # 某个区域内出现了，加强buffer开始，就按按到buffer瞬间消失
            # if debugMode == 'DEBUG':
            #     drawRec(int(w), int(h), (int(x), int(y)), win32api.RGB(0, 255, 0), width=8)

            # 仅仅获取颜色，没有任何动作
            log.debug("ddyy-yehaibo:1:" + str(self.WABloodBarX + self.WABloodBarWidth * float(iPercentage)))
            log.debug("ddyy-yehaibo:2:" + str(self.WABloodBarY))
            log.debug("ddyy-yehaibo:3:" + str(self.WABloodBarDeltaX))
            log.debug("ddyy-yehaibo:4:" + str(self.WABloodBarDeltaY))
            sleep(sleepSecond)  # 避免CPU占用太高
            ################################Button1##########################################
            imButton1 = ImageGrab.grab(
                bbox=(self.WABloodBarX + self.WABloodBarWidth * float(iPercentage), self.WABloodBarY - 6, self.WABloodBarX + self.WABloodBarWidth * float(iPercentage) + self.WABloodBarDeltaX, self.WABloodBarY - 6 + self.WABloodBarDeltaY))  # X1,Y1,X2,Y2
            imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
                (imButton1.size[1], imButton1.size[0], 3))
            imButton1_pil = Image.fromarray(imButton1_numpy)
            rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
            avgButton1_color = 0
            if RGBMode == 'r':
                rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = rButton1.getpixel((0, 0))
            elif RGBMode == 'g':
                gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = gButton1.getpixel((0, 0))
            elif RGBMode == 'b':
                bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
                avgButton1_color = bButton1.getpixel((0, 0))
            log.debug("ddyy-yehaibo:5:" + str(avgButton1_color))
            return avgButton1_color
        else:
            return 0

    def removeFinishedTrhead(self, threadPool):
        log.debug("removeFinishedTrhead:为了避免关闭无效的线程而导致异常，源数组长度:" + str(len(threadPool)))
        threadPoolNewAvaliable = []
        for obj in threadPool:
            if obj.is_alive() == True:
                threadPoolNewAvaliable.append(obj)

        threadPool.clear()
        for obj in threadPoolNewAvaliable:
            threadPool.append(obj)
        log.debug("removeFinishedTrhead:为了避免关闭无效的线程而导致异常，之后数组长度:" + str(len(threadPool)))
        return

    def interruptAllByForce(self):
        # 强制打断、终止一切键盘鼠标操作77
        # 这里的顺序非常重要，会直接导致是否能打断，比如 h 上马是否可以上马
        if len(self.threadPoolMouse) > 0:
            self.removeFinishedTrhead(self.threadPoolMouse)
            for obj in self.threadPoolMouse:
                obj.terminate()
            self.threadPoolMouse.clear()

        if len(self.threadPoolKeyboard) > 0:
            for obj in self.threadPoolKeyboard:
                obj.terminate()
            self.removeFinishedTrhead(self.threadPoolKeyboard)
            self.threadPoolKeyboard.clear()
        #  stage2:
        # 终止掉别人| 所有的鼠标操作哦
        #  stage1:

        # stage3:

        self.sem.release()
        return

    def interruptAllByForceMouseUpDown(self):
        # 强制打断、终止一切键盘鼠标操作77
        # 这里的顺序非常重要，会直接导致是否能打断，比如 h 上马是否可以上马

        #  stage1:
        if len(self.threadPoolMouse) > 0:
            self.removeFinishedTrhead(self.threadPoolMouse)

        if len(self.threadPoolKeyboard) > 0:
            self.removeFinishedTrhead(self.threadPoolKeyboard)

        #  stage2:
        # 终止掉别人| 所有的鼠标操作哦
        if len(self.threadPoolKeyboard) > 0:
            for obj in self.threadPoolKeyboard:
                obj.terminate()
        if len(self.threadPoolMouse) > 0:
            for obj in self.threadPoolMouse:
                obj.terminate()

        # stage3:
        if len(self.threadPoolKeyboard) > 0:
            self.threadPoolKeyboard.clear()

        if len(self.threadPoolMouse) > 0:
            self.threadPoolMouse.clear()

        self.sem.release()
        return

    # 终止线程
    def _async_raise(self, tid, exctype):
        """raises the exception, perforself.ms cleanup if needed"""
        tid = ctypes.c_long(tid)
        if not inspect.isclass(exctype):
            exctype = type(exctype)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            # """if it returns a number greater than one, you're in trouble,
            # and you should call it again with exc=NULL to revert the effect"""
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
            raise SystemError("PyThreadState_SetAsyncExc failed")
        return

    def stopThread(self, thread):
        self._async_raise(thread.ident, SystemExit)
        return

    def press(self, key):
        self.kb.press(key)
        self.kb.release(key)
        return

    def sleep(self, n):
        time.sleep(n)
        return

    def logAop(self, func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)

        return wrapper

    # 修饰器参数的情况
    def loggerAop(self, pram):
        def logAop(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                print('call %s(): and parsms is %s' % (func.__name__, pram))
                return func(*args, **kw)

            return wrapper

        return logAop

    # ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★下面是鼠标区域★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    # 监听鼠标
    def on_mouse_move_inThread(self, x, y):
        # 【鼠标移动】是非常有并发运行的需求的，因此不需要做不可并行的控制
        # with self.sem:
        strUuid = random.randint(1, 50000)
        log.debug('步骤 1:' + str(strUuid))
        # self.sem.release()
        # self.sem.acquire()
        # 动作代码
        position = format(self.ms.position)
        log.debug("-------------------->当前鼠标位置为:" + str(position) + "<--------------------")
        self.mouseMove(x, y)
        # self.sem.release()
        if self.gcDuringMousemoveObj == 'True':
            if int(datetime.datetime.now().strftime('%S')) % 20 == 0:
                log.debug("○○○○○释放了一次内存○○○○○")
                gc.collect()

        return

    # 监听鼠标
    def on_mouse_move_parent(self, x, y):
        # try:
        #     # # 不放到线程做了，直接在这里触发
        #     # log.debug(str(i) + ':Pointer moved in inner to {0}'.format((x, y)))
        #     if self.ui.checkBox_XY_DISPLAY.isChecked() == True:
        #         self.MainWindow.setWindowTitle("XY:" + str(x) + "<----->" + str(y))
        #     if self.stillCanCreateNewThread:

        #         if int(datetime.datetime.now().strftime('%S')) % 4 == 0:
        #             # # 鼠标消耗内存特别快，因此要控制线程的创建速度(delete)
        #             # p = threadJob(target=self.on_mouse_move_inThread, args=(x, y))
        #             # self.threadPoolMouse.append(p)
        #             # p.start()
        #             pass
        #         if int(datetime.datetime.now().strftime('%S')) % 4 == 0:
        #             # removeFinishedTrhead(self.threadPoolKeyboard)
        #             pass
        #         if int(datetime.datetime.now().strftime('%S')) % 6 == 0:
        #             # 鼠标池中特别多，因此最好不好在这里频繁释放，否则直接影响游戏体验
        #             # removeFinishedTrhead(self.threadPoolMouse)
        #             pass
        #     return True
        # except Exception as ex:
        #     log.error('异常信息:' + str(ex))
        # finally:
        #     return True
        pass

    def on_mouse_click_parent(self, x, y, button, pressed):
        # try:
        #     log.debug(
        #         "on_mouse_click_parent--1   是否还可以在内存中创建self.stillCanCreateNewThread:" + str(
        #             self.stillCanCreateNewThread) + ", 左右键:" + str(
        #             button) + ", pressed:" + str(pressed))
        #     if pressed == True:
        #         # 鼠标点击下去了
        #         if self.stillCanCreateNewThread:
        #             log.debug('{0} at {1}'.format(
        #                 'Pressed' if pressed else 'Released',
        #                 (x, y)))
        #             # Button.left
        #             log.debug("on_mouse_click_parent button:" + str(button))
        #             log.debug("on_mouse_click_parent--2--[比较重要的三个主要终止别人的处理顺序，不能错了]")
        #             # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #             # self.interruptAllByForce()
        #             # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #             # 通过多肽调用这个函数，这个函数很有可能会被子类中重写了(不走线程)
        #             self.on_mouse_click_son_before_thread(x, y, button, pressed)
        #             if button == Button.left:
        #                 log.debug("on_mouse_click_inThread:点击了鼠标左边")
        #                 self.mouseLeftClickNoThread(x, y, pressed)
        #             elif button == Button.right:
        #                 log.debug("on_mouse_click_inThread:点击了鼠标右边")
        #                 self.mouseRightClickNoThread(x, y, pressed)

        #             # 上面是非线程的处理方式
        #             # 下面是线程的处理方式
        #             p1 = threadJob(target=self.on_mouse_click_inThread, args=(x, y, button, pressed))
        #             self.threadPoolMouse.append(p1)
        #             log.debug("on_mouse_click_parent--9:鼠标点击所新创建的线程，已经被创建。")
        #             p1.start()

        #         return True
        #     else:
        #         # 鼠标释放开
        #         return True
        # except Exception as ex:
        #     log.error('异常信息:' + str(ex))
        # finally:
        #     return True
        pass

    # 沒有綫程方式的調用
    def on_mouse_click_son_before_thread(self, x, y, button, pressed):
        # 在鼠标点击，终止和打断其他动作（有些职业需要，有些不需要）??????????
        self.interruptAllByForce()
        return

    # 沒有綫程
    def mouseLeftClickNoThread(self, x, y, pressed):
        pass
        return

    # 沒有綫程
    def mouseRightClickNoThread(self, x, y, pressed):
        pass
        return

    def on_mouse_scroll_parent(self, x, y, dx, dy):
        try:
            if self.stillCanCreateNewThread:
                log.debug("on_mouse_scroll_parent:1")
                log.debug('on_mouse_scroll_parent {0} at {1}'.format(
                    'down' if dy < 0 else 'up',
                    (x, y)))
                # 通过多肽调用这个函数，这个函数很有可能会被子类中重写了
                self.on_mouse_scroll_son_before_thread(dx, dy)
                log.debug("on_mouse_scroll_parent:2")
                self.removeFinishedTrhead(self.threadPoolKeyboard)
                p = threadJob(target=self.on_mouse_scroll_inThread, args=(x, y, dx, dy))
                self.threadPoolMouse.append(p)
                log.debug("on_mouse_scroll_parent:3:创建线程成功!")
                p.start()
            return True
        except Exception as ex:
            log.error('异常信息:' + str(ex))
        finally:
            return True

    def on_mouse_scroll_son_before_thread(self, dx, dy):
        if dy < 0:
            # 滚轮向下
            pass
        elif dy > 0:
            # 滚轮向上
            pass
        return

    def on_mouse_scroll_inThread(self, x, y, dx, dy):

        log.debug("on_mouse_click_inThread:在self.sem之前")
        self.ui.stopLoop = False
        with self.sem:
            log.debug("on_mouse_click_inThread:进入了self.sem")
            self.sem.release()
            self.sem.acquire()
            # self.frozenMouseScroll = True
            if dy < 0:
                log.debug("on_mouse_click_inThread:进入了self.sem->mouseDown_before")
                self.mouseDown(x, y)
                log.debug("on_mouse_click_inThread:进入了self.sem->mouseDown_after")
            elif dy > 0:
                log.debug("on_mouse_click_inThread:进入了self.sem->mouseUp")
                self.mouseUp(x, y)
            # 动作代码
            self.sem.release()
            # self.frozenMouseScroll = False
        return

    def on_mouse_click_inThread(self, x, y, button, pressed):
        # 【鼠标移动】是非常需要严格控制并发需求
        self.sem.release()
        self.sem.acquire()
        # 动作代码
        if button == Button.left:
            log.debug("on_mouse_click_inThread:点击了鼠标左边")
            self.mouseLeftClick(x, y)
        elif button == Button.right:
            log.debug("on_mouse_click_inThread:点击了鼠标右边")
            self.mouseRightClick(x, y)
        self.sem.release()
        return

    # ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★下面是键盘区域★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    # 键盘监听(顶层)
    def on_keyboard_press_parent(self, key):
        try:
            if key.char == 'z':
                self.ui.stopLoop = True
            else:
                # self.ui.stopLoop = False
                pass
        except Exception as ex:
            # self.ui.stopLoop = False
            pass

        try:
            if key.char == Key.cmd:
                self.ui.stopLoop = True
            else:
                # self.ui.stopLoop = False
                pass
        except Exception as ex:
            # self.ui.stopLoop = False
            pass

        log.debug("on_keyboard_press_parent:类里面了a1")
        try:
            # 这些拦截的是房子重复按，重复触发事件，进入一个死循环。这些按键上会承载一个图标。【press】和【release】都有的。
            # 阻止for循环，这些都是手不会直接按到的按键
            if key in (
                    Key.f1, Key.f2, Key.f3, Key.f4, Key.f5, Key.f6, Key.f7, Key.f8, Key.f9, Key.f10, Key.f11, Key.f12):
                return True
            if key not in (
                    Key.caps_lock, Key.shift, Key.shift_l, Key.shift_r, Key.ctrl_l, Key.ctrl_r, Key.alt_l, Key.alt_r,
                    Key.alt, Key.space, Key.cmd):
                # caps_lock, shift等这些，是允许过去的，是触发并发按键逻辑的。
                # 下面是预留按键，不运行从键盘进行出发，只能从代码进行触发
                if key.char in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0'):
                    return True
                if key.char in ('y', 'u', 'i', 'o', 'p', 'j', 'k', 'l', 'n', 'm'):
                    return True
                if key.char in ('=', '-', '\\', ']', '[', '\'', ';', '/', '.', ','):
                    return True
                # 避免重复键盘按键导致的重复多线程的生成
                if key.char in self.ui.RUNNING_KEY_POOL:
                    # 如果已经有运行的键位了，在这里就直接return，直接终止
                    return True
                else:
                    # 没有就添加到界面唯一的数组中，标记这个键位置已经运行了，个别按键不是大量的动作，又要求可以允许重复按的
                    if key.char not in ('v', 'r', 'q', 'w', 'x', 'c', 'h'):
                        self.ui.RUNNING_KEY_POOL.append(key.char)
                    else:
                        if 'a' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('a')
                        if 'A' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('A')
                        if 'q' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('q')
                        if 'Q' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('Q')
                    #
                    if key.char in ('a', 'A', 'q', 'Q'):
                        self.ui.stopLoop = False
                    # z(终止键，立刻释放公共数组)
                    if key.char in ('z', 'Z'):
                        self.ui.stopLoop = True
                        self.ui.RUNNING_KEY_POOL.clear()
                    # 到这里的逻辑是手指头实际会物理点击的按键，就会周到这里的流程
                    log.debug("on_keyboard_press_parent:类里面了a2")
                    if self.stillCanCreateNewThread:
                        self.removeFinishedTrhead(self.threadPoolKeyboard)
                        log.debug("on_keyboard_press_parent:类里面了a3")
                        self.on_keyboard_press_son_before_thread(key)

                        log.debug("on_keyboard_press_parent:类里面了a4")
                        # removeFinishedTrhead(self.threadPoolKeyboard)
                        log.debug("on_keyboard_press_parent:类里面了a5")
                        # 上面的代码，决定了是否要终止别人的
                        p = threadJob(target=self.on_keyboard_press_inThread, args=(key,))
                        self.threadPoolKeyboard.append(p)
                        log.debug('线程池中增加一个数组元素, 当前键盘pool长度:' + str(len(self.threadPoolKeyboard)))
                        p.start()
                        log.debug('线程开始start')
                        log.debug("on_keyboard_press_parent:类里面了a6")
                    return True
            else:
                # 左atl，右atl等稍微特殊得键，这些键位，暂时不用ui.RUNNING_KEY_POOL来进行管理，因为他们的入口键位a已经被管理起来了
                # 到这里的逻辑是手指头实际会物理点击的按键，就会周到这里的流程
                log.debug("on_keyboard_press_parent:类里面了a2")
                if self.stillCanCreateNewThread:
                    self.removeFinishedTrhead(self.threadPoolKeyboard)
                    log.debug("on_keyboard_press_parent:类里面了a3")
                    self.on_keyboard_press_son_before_thread(key)

                    log.debug("on_keyboard_press_parent:类里面了a4")
                    # removeFinishedTrhead(self.threadPoolKeyboard)
                    log.debug("on_keyboard_press_parent:类里面了a5")
                    # 上面的代码，决定了是否要终止别人的
                    p = threadJob(target=self.on_keyboard_press_inThread, args=(key,))
                    self.threadPoolKeyboard.append(p)
                    log.debug('线程池中增加一个数组元素, 当前键盘pool长度:' + str(len(self.threadPoolKeyboard)))
                    p.start()
                    log.debug('线程开始start')
                    log.debug("on_keyboard_press_parent:类里面了a6")
                return True
        except Exception as ex:
            log.error('异常信息:special key {0} pressed'.format(
                key) + str(ex))
        finally:
            # 普通的，1，2，3，4，5，6，7，8，9，0，都会经过这里的，所以不能打日志。
            # log.debug("on_keyboard_press:函数   key.char:" + str(key.char) + ", self.stillCanCreateNewThread:" + str(
            #     self.stillCanCreateNewThread) + "__5")
            # 这个返回至关重要，避免许多异常情况
            return True

    def on_keyboard_press_son_before_thread(self, key):
        # 这一句非常重要，否则按键触发的界面循环事件，就不会改变和触发这个变量，在最前部写个即可
        self.ui.stopLoop = False
        # 有些按键是直接终止别人的，继续自己的，有些不是这样的，因此要区别对待【排列组合，情况非常多】/【也要超级符合每个职业的操作习惯】
        if key in (
                Key.f1, Key.f2, Key.f3, Key.f4, Key.f5, Key.f6, Key.f7, Key.f8, Key.f9, Key.f10, Key.f11,
                Key.f12):
            pass
        elif key == Key.enter:
            pass
        elif key == Key.space:
            pass
        elif key not in (
                Key.caps_lock, Key.shift, Key.shift_l, Key.shift_r, Key.ctrl_l, Key.ctrl_r, Key.alt_l, Key.alt_r,
                Key.alt, Key.space):
            if key.char == 'a':
                # 不终止别人，后面让只允许一个线程执行的逻辑来顺序排
                # ★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|
                pass
            elif key.char == 'z':
                self.ui.stopLoop = True
                pass
            elif key.char == 'q':
                log.debug("on_keyboard_press_son_before_thread:函数   key.char:" + str(
                    key.char) + ", self.stillCanCreateNewThread:" + str(
                    self.stillCanCreateNewThread) + "__1.b")
                pass
                log.debug("on_keyboard_press_son_before_thread:函数   key.char:" + str(
                    key.char) + ", self.stillCanCreateNewThread:" + str(
                    self.stillCanCreateNewThread) + "__1.c")
            elif key.char == 'w':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'r':
                # 终止掉别人
                # interruptAllByForce()
                pass
            elif key.char == 'g':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'x':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'v':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'h':
                # 终止掉别人
                # self.interruptAllByForce()
                pass
            elif key.char == 'c':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'e':
                pass
            elif key.char == 's':
                pass
            elif key.char == 'd':
                pass
            elif key.char == 'f':
                pass
            elif key.char == 'b':
                pass
        return

    # 键盘监听(最顶层的键盘监听函数)
    def on_keyboard_release_parent(self, key):
        try:
            # 这些拦截的是房子重复按，重复触发事件，进入一个死循环。这些按键上会承载一个图标。【press】和【release】都有的。
            # 阻止for循环，这些都是手不会直接按到的按键
            if key in (
                    Key.f1, Key.f2, Key.f3, Key.f4, Key.f5, Key.f6, Key.f7, Key.f8, Key.f9, Key.f10, Key.f11, Key.f12):
                return True
            if key not in (
                    Key.caps_lock, Key.shift, Key.shift_l, Key.shift_r, Key.ctrl_l, Key.ctrl_r, Key.alt_l, Key.alt_r,
                    Key.alt, Key.space, Key.cmd):
                # caps_lock, shift等这些，是允许过去的，是触发并发按键逻辑的。
                if key.char in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0'):
                    return True
                if key.char in ('y', 'u', 'i', 'o', 'p', 'j', 'k', 'l', 'n', 'm'):
                    return True
                if key.char in ('=', '-', '\\', ']', '[', '\'', ';', '/', '.', ','):
                    return True
            try:
                log.debug("进入了:on_keyboard_release_parent:函数   key.char:" + str(key.char))
            except Exception as ex:
                pass
            if self.stillCanCreateNewThread == False:
                log.debug(
                    "目前的 on_keyboard_release_parent self.stillCanCreateNewThread == False，也就是暂时无法在内存中创建新的线程。（通常我们可以停下来打字聊天了。）")
            log.debug('{0} released'.format(
                key))
            if key == keyboard.Key.esc:
                # Stop listener
                return False
            elif key == Key.cmd:
                log.debug('对于评级战场，按下windows键盘，就重新启动一次程序')
                self.ui.stopLoop = True
                # self.removeFinishedTrhead(self.threadPoolKeyboard)
                # self.removeFinishedTrhead(self.threadPoolMouse)
                # for obj in self.threadPoolKeyboard:
                #     obj.terminate()
                #     log.debug('循环杀死键盘的python线程,finished!')
                # for obj in self.threadPoolMouse:
                #     obj.terminate()
                #     log.debug('循环杀死鼠标的python线程,finished')
                # self.threadPoolKeyboard.clear()
                # self.threadPoolMouse.clear()
                # self.sem.release()
                self.windowCmd()
                return False
            elif key.char == 'z':
                self.z()
                log.debug(
                    "进入了:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz11")
                log.debug('进入z的终止处理过程')
                self.removeFinishedTrhead(self.threadPoolKeyboard)
                self.removeFinishedTrhead(self.threadPoolMouse)
                for obj in self.threadPoolKeyboard:
                    obj.terminate()
                    log.debug('循环杀死键盘的python线程,finished!')
                for obj in self.threadPoolMouse:
                    obj.terminate()
                    log.debug('循环杀死鼠标的python线程,finished')
                self.threadPoolKeyboard.clear()
                self.threadPoolMouse.clear()
                self.sem.release()
                # 按Z，还顺便释放一次内存
                gc.collect()
                log.debug('清理完成后的键盘线程池长度为:' + str(len(self.threadPoolKeyboard)))
                log.debug('清理完成后的鼠标线程池长度为:' + str(len(self.threadPoolMouse)))
                log.debug(
                    "进入了:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz22")
                return True
            else:
                # 起码return一个true，否则按a键，都不会再监听了
                return True
        except Exception as ex:
            log.error('异常信息:1 {0} pressed'.format(
                key) + str(ex))
        finally:
            # 这个返回至关重要，避免许多异常情况
            return True

    def on_keyboard_press_inThread(self, key):
        log.debug("on_keyboard_press_inThread:1")
        # with self.sem:
        log.debug("on_keyboard_press_inThread:2")
        self.sem.release()
        log.debug("on_keyboard_press_inThread self.sem.release() after 2")
        self.sem.acquire()
        log.debug("on_keyboard_press_inThread self.sem.acquire() after 3")
        self.frozenKeyPress = True
        # self.ui.stopLoop = False
        # 动作代码
        if key == Key.enter:
            log.debug('on_keyboard_press_inThread 线程内部打印的enter键位')
        elif key == Key.space:
            self.space()
        elif key == Key.f1:
            pass
        elif key == Key.f2:
            pass
        elif key == Key.f3:
            pass
        elif key == Key.f4:
            pass
        elif key == Key.f5:
            pass
        elif key == Key.f6:
            pass
        elif key == Key.f7:
            pass
        elif key == Key.f8:
            pass
        elif key == Key.f9:
            pass
        elif key == Key.f10:
            pass
        elif key == Key.f11:
            pass
        elif key == Key.f12:
            pass
        elif key == Key.cmd:
            self.windowCmd()
        elif key == Key.alt_l:
            # 2  alt
            self.parallelAlt2()
        elif key == Key.caps_lock:
            # 3   caps_lock
            self.parallelCap3()
        elif key == Key.shift:
            # 4   shift
            self.parallelShift4()
        elif key == Key.ctrl_l:
            # 5   ctrl
            self.parallelCtrl5()
        elif key == Key.ctrl_r:
            # 5   ctrl
            self.parallelCtrl6()
        # ========================================上面是特殊键盘，下面是a，b，c的键，key和key.char会报异常的
        elif key.char == 'a':
            log.debug("on_keyboard_press_inThread 按下键盘【a】后，正式开始执行：on_keyboard_press_inThread:3")
            self.a()
        elif key.char == 'z':
            log.debug('线程:z-->终止')
            self.ui.stopLoop = True
            # player.z(clearListen)
            # pauseListen(False)
            # clearListen(True)
            # self.threadPoolMouse.clear()
            log.debug('成功清空self.threadPoolKeyboard')
        elif key.char == 'q':
            self.q()
        elif key.char == 'w':
            self.w()
        elif key.char == 'r':
            self.r()
        elif key.char == 'g':
            self.g()
        elif key.char == 'x':
            self.x()
        elif key.char == 'v':
            self.v()
        elif key.char == 'h':
            self.h()
        elif key.char == 'c':
            self.c()
        elif key.char == 'e':
            self.e()
        elif key.char == 's':
            self.s()
        elif key.char == 'd':
            self.d()
        elif key.char == 'f':
            self.f()
        elif key.char == 'b':
            self.b()
        # 对漏掉的字符的判断
        elif key.char == 'm':
            self.m()
        elif key.char == 'n':
            self.n()
        elif key.char == 't':
            self.t()
        elif key.char == 'y':
            self.y()
        elif key.char == 'u':
            self.u()
        elif key.char == 'i':
            self.i()
        elif key.char == 'o':
            self.o()
        elif key.char == 'p':
            self.p()
        elif key.char == 'j':
            self.j()
        elif key.char == 'k':
            self.k()
        elif key.char == 'l':
            self.l()
        # 对特殊字符的判断---------------这里是原始自定义映射关系的地方---->/1 .2 ,3 '4 ;5 \6 ]7 [8 =9 -0
        elif key.char == '/':
            self.special1()
        elif key.char == '.':
            self.special2()
        elif key.char == ',':
            self.special3()
        elif key.char == '\'':
            self.special4()
        elif key.char == ';':
            self.special5()
        elif key.char == '\\':
            self.special6()
        elif key.char == ']':
            self.special7()
        elif key.char == '[':
            self.special8()
        elif key.char == '=':
            self.special9()
        elif key.char == '-':
            self.special10()
        elif key == Key.f12:
            print(
                '***********************yehaibo kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk***********************')
        elif key == Key.f13:
            self.f13()
        # 最多5个并发技能的按键------------------parallel--------------------> parallel:`1   Alt2     cap3    shift4   ctrl5
        elif key.char == '`':
            # 1  `
            self.parallel1()

        self.sem.release()

        self.frozenKeyPress = False
        return

    def click(self, kb, ascii, times):
        log.debug("进入click:" + str(times))
        for i in range(0, int(times)):
            self.kb.press(ascii)
            sleep(0.016)
            self.kb.release(ascii)
            sleep(0.016)
            log.debug("****************单击click press:" + str(ascii) + " button(times):" + str(i) + "/" + str(
                times) + "****************")
        log.debug("离开click:" + str(times))
        return

    # @abstractmethod  # 调用@abstractmethod规定子类必须有pay方法
    def a(self):
        log.debug('★按下键盘a后，需要开始执行的内容★')
        # sleep(10)
        for i in range(1, 888888):
            self.click(self.kb, '1', 8)
            sleep(0.08)
            self.click(self.kb, '2', 8)
            sleep(0.08)
            self.click(self.kb, '3', 8)
            sleep(0.08)
            self.click(self.kb, '4', 8)
            sleep(0.08)
            self.click(self.kb, '5', 8)
            sleep(0.08)
        log.debug('★按下键盘a后，需要over执行的内容★')
        return

    def z(self):
        # ====================================================和某个键的作用要是一样的，因为习惯于，按住z不动，可是实际的操作要的是不停的z点击
        # #showtooltip 死亡缠绕
        # /stopcasting
        # 单引号，需要执行上面的宏，这样才能干净地打断残余施法
        # ====================================================[开始]终止定时器的操作====================================================
        log.info('in z():' + str(self.ui.stopLoop))
        try:
            self.ui.stopLoop = True
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame1.pause_job(job_id='yehaibo1')
            self.schedulerInGame1.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame2.pause_job(job_id='yehaibo2')
            self.schedulerInGame2.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame3.pause_job(job_id='yehaibo3')
            self.schedulerInGame3.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame4.pause_job(job_id='yehaibo4')
            self.schedulerInGame4.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame5.pause_job(job_id='yehaibo5')
            self.schedulerInGame5.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame6.pause_job(job_id='yehaibo6')
            self.schedulerInGame6.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame7.pause_job(job_id='yehaibo7')
            self.schedulerInGame7.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame8.pause_job(job_id='yehaibo8')
            self.schedulerInGame8.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame9.pause_job(job_id='yehaibo9')
            self.schedulerInGame9.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame10.pause_job(job_id='yehaibo10')
            self.schedulerInGame10.remove_all_jobs()
        except Exception as ex:
            pass
        # ====================================================[结束]终止定时器的操作====================================================
        try:
            # 清空界面运行池
            self.ui.RUNNING_KEY_POOL.clear()
        except Exception as ex:
            pass
        finally:
            self.ui.stopLoop = True
            log.debug('全局开关:' + str(self.ui.stopLoop))
        # 打断法术
        for i in range(1, 2):
            self.click(self.kb, '\'', 1)
            sleep(0.1)
        # 直接终止一切鼠标，键盘动作。
        log.debug('全局开关interruptAllByForce:之前')
        self.interruptAllByForce()
        log.debug('全局开关interruptAllByForce:之后')
        return

    def u(self):
        # ====================================================和某个键的作用要是一样的，因为习惯于，按住z不动，可是实际的操作要的是不停的z点击
        # 本质上的单击是这里
        # ====================================================[开始]终止定时器的操作====================================================
        log.info('in u():' + str(self.ui.stopLoop))
        try:
            self.ui.stopLoop = True
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame1.pause_job(job_id='yehaibo1')
            self.schedulerInGame1.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame2.pause_job(job_id='yehaibo2')
            self.schedulerInGame2.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame3.pause_job(job_id='yehaibo3')
            self.schedulerInGame3.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame4.pause_job(job_id='yehaibo4')
            self.schedulerInGame4.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame5.pause_job(job_id='yehaibo5')
            self.schedulerInGame5.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame6.pause_job(job_id='yehaibo6')
            self.schedulerInGame6.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame7.pause_job(job_id='yehaibo7')
            self.schedulerInGame7.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame8.pause_job(job_id='yehaibo8')
            self.schedulerInGame8.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame9.pause_job(job_id='yehaibo9')
            self.schedulerInGame9.remove_all_jobs()
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            # self.schedulerInGame10.pause_job(job_id='yehaibo10')
            self.schedulerInGame10.remove_all_jobs()
        except Exception as ex:
            pass
        # ====================================================[结束]终止定时器的操作====================================================
        try:
            # 清空界面运行池
            self.ui.RUNNING_KEY_POOL.clear()
        except Exception as ex:
            pass
        finally:
            self.ui.stopLoop = True
            log.debug('全局开关:' + str(self.ui.stopLoop))
        # 打断法术
        for i in range(1, 2):
            self.click(self.kb, '\'', 1)
            sleep(0.1)
        # 直接终止一切鼠标，键盘动作。
        log.debug('全局开关interruptAllByForce:之前')
        self.interruptAllByForce()
        log.debug('全局开关interruptAllByForce:之后')
        return

    def q(self):
        log.debug('★按下键盘q后，需要开始执行的内容★')
        for i in range(1, 888888):
            self.click(self.kb, '[', 8)
            sleep(0.08)
            self.click(self.kb, ']', 8)
        log.debug('★按下键盘q后，需要over执行的内容★')
        return

    def w(self):
        log.debug('★按下键盘w后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘w后，需要over执行的内容★')
        return

    def r(self):
        log.debug('★按下键盘r后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘r后，需要over执行的内容★')
        return

    def g(self):
        log.debug('★按下键盘g后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘g后，需要over执行的内容★')
        return

    def x(self):
        log.debug('★按下键盘x后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘x后，需要over执行的内容★')
        return

    def v(self):
        log.debug('★按下键盘v后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘v后，需要over执行的内容★')
        return

    def h(self):
        log.debug('★按下键盘h后，需要开始执行的内容★')
        # 骑马
        self.click(self.kb, Key.delete, 1)
        log.debug('★按下键盘h后，需要over执行的内容★')
        return

    def c(self):
        log.debug('★按下键盘c后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘c后，需要over执行的内容★')
        return

    def e(self):
        log.debug('★按下键盘e后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘e后，需要over执行的内容★')
        return

    def s(self):
        log.debug('★按下键盘s后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘s后，需要over执行的内容★')
        return

    def d(self):
        log.debug('★按下键盘d后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘d后，需要over执行的内容★')
        return

    def f(self):
        log.debug('★按下键盘f后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘f后，需要over执行的内容★')
        return

    def b(self):
        log.debug('★按下键盘b后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘b后，需要over执行的内容★')
        return

    def m(self):
        sleep(10)
        return

    def n(self):
        sleep(10)
        return

    def t(self):
        sleep(10)
        return

    def y(self):
        sleep(10)
        return

    def u(self):
        sleep(10)
        return

    def i(self):
        sleep(10)
        return

    def o(self):
        sleep(10)
        return

    def p(self):
        sleep(10)
        return

    def j(self):
        sleep(10)
        return

    def k(self):
        sleep(10)
        return

    def l(self):
        sleep(10)
        return

    # 对特殊字符的函数定义 ：/1 .2 ,3 '4 ;5 \6 ]7 [8 =9 -10 `11
    def special1(self):
        # /
        sleep(2)
        return

    def special2(self):
        # .
        sleep(2)
        return

    def special3(self):
        # ,
        sleep(2)
        return

    def special4(self):
        # '
        sleep(2)
        return

    def special5(self):
        # ;
        sleep(2)
        return

    def special6(self):
        # \
        sleep(2)
        return

    def special7(self):
        # ]
        sleep(2)
        return

    def special8(self):
        # [
        sleep(2)
        return

    def special9(self):
        # =
        sleep(2)
        return

    def special10(self):
        # -
        sleep(2)
        return

    def f12(self):
        # f12
        sleep(2)
        return

    def f13(self):
        # f13
        sleep(2)
        return

    def parallel1(self):
        # `--1
        sleep(2)
        return

    def parallelAlt2(self):
        # alt--2
        sleep(2)
        return

    def parallelCap3(self):
        # Cap--3
        sleep(2)
        return

    def parallelShift4(self):
        # Shift--4
        sleep(2)
        return

    def parallelCtrl5(self):
        # Ctrl--5
        sleep(2)
        return

    def parallelCtrl6(self):
        # Ctrl--5
        sleep(2)
        return

    def windowCmd(self):
        # ★★★★★★★★★★★★★★★★★★★★★★特殊的windows键盘，这个用户评级战场的重启★★★★★★★★★★★★★★★★★★★★★★
        for i in range(1, 4):
            # 如果不执行这里，就会在黑色的框上点击鼠标，那么就直接停止执行批处理了，也就无法终止程序，也就没法重启了
            self.ExecutemouseMove(1650, 850)
            self.click(self.kb, 'z', 2)
            self.ExecutemouseMove(1650, 850)
            sleep(0.3)
            self.ExecutemouseMove(1650, 850)
        self.ExecutemouseMove(1650, 850)
        sleep(0.3)
        self.ExecutemouseMove(1650, 850)
        # 避免批处理弹出黑框
        win32api.ShellExecute(0, 'open', getIni("../util", "bat", "batFilePath"), '', '', 0)
        # os.system(getIni("../util", "bat", "batFilePath"))
        self.ExecutemouseMove(1650, 850)
        return

    def space(self):
        log.debug('★按下键盘space后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘space后，需要over执行的内容★')
        return

    def mouseUp(self, x, y):
        log.debug('★鼠标向上滚，需要开始执行的内容★')
        sleep(10)
        log.debug('★鼠标向上滚，需要over执行的内容★')
        return

    def mouseDown(self, x, y):
        log.debug('★鼠标向下滚，需要开始执行的内容★')
        sleep(10)
        log.debug('★鼠标向下滚，需要over执行的内容★')
        return

    def mouseMove(self, x, y):
        log.debug('★鼠标mouself.semove，需要开始执行的内容★')
        log.debug('★鼠标mouself.semove，需要over执行的内容★')
        return

    def ExecutemouseMove(self, x, y):
        log.debug('★鼠标mouself.ExecutemouseMove，需要开始执行的内容★')
        self.ms.position = (0, 0)
        self.ms.move(x, y)
        log.debug('★鼠标mouself.ExecutemouseMove，需要over执行的内容★')
        return

    def mouseLeftClick(self, x, y):
        log.debug('★鼠标click-left，需要开始执行的内容★')
        log.debug('★鼠标click-left，需要over执行的内容★')
        return

    def ExecutemouseLeftClick(self):
        log.debug('★纯执行鼠标动作，为了配合自动排评级战场★')
        self.ms.press(Button.left)
        self.ms.release(Button.left)
        return

    def mouseRightClick(self, x, y):
        log.debug('★鼠标click-right，需要开始执行的内容★')
        log.debug('★鼠标click-right，需要over执行的内容★')
        return

    def ExecutemouseRightClick(self):
        log.debug('★纯执行鼠标动作，为了配合自动排评级战场★')
        self.ms.press(Button.right)
        self.ms.release(Button.right)
        return

    def startListen(self):
        # wrong here
        # startMouseListen()
        # self.kb.
        pass

    def pubAvgColorCDNumberDeductInBlock(self, blockx, blocky, width, height, color, waitSeconds, pressKey, bigsmall,
                                         avgColor):
        avgColor1 = self.pubAvgColorNoTrigger(blockx, blocky, width, height, color, waitSeconds)
        if bigsmall == 'b':
            while avgColor1 > avgColor:
                self.click(self.kb, pressKey, 8)
                sleep(0.01)
                avgColor1 = self.pubAvgColorNoTrigger(blockx, blocky, width, height, color, waitSeconds)
        if bigsmall == 's':
            while avgColor1 < avgColor:
                self.click(self.kb, pressKey, 8)
                sleep(0.01)
                avgColor1 = self.pubAvgColorNoTrigger(blockx, blocky, width, height, color, waitSeconds)
        return

    def TimeSecondModZero(self, modNumber):
        now_time = datetime.datetime.now()
        # time1_str = now_time.strftime('%Y-%m-%d %H:%M:%S %f')
        SecondStr = now_time.strftime('%S')
        SecondInt = int(SecondStr)
        if SecondInt % modNumber == 0:
            return True
        else:
            return False

    def schedulerAction(self):
        pass
        return


if __name__ == '__main__':
    playerDebug = Player()
    # 调试主题函数
    print(playerDebug.TimeSecondModZero(2))
